package com.chen;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Range;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.face.LBPHFaceRecognizer;
import org.opencv.highgui.HighGui;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

/**
 *
 * @author scorpius
 */
public class IdentificationMark {

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }
    static CascadeClassifier cascade = new CascadeClassifier("/usr/local/share/opencv4/haarcascades/haarcascade_frontalface_default.xml");

    /**
     * 脸部检测并标注
     *
     * @param rgb RGB图像
     * @param gray 灰度图像
     * @return 图像与脸坐标
     */
    public static List<Map<Mat,Point>> faceAnalysis(Mat rgb, Mat gray) {
        if (cascade.empty()) {
            System.err.println("文件路径有误...");
            return new ArrayList<>();
        }
        if (cascade.empty()) {
            System.out.println("文件读取失败");
            return new ArrayList<>();
        }
        MatOfRect rect = new MatOfRect();
        cascade.detectMultiScale(gray, rect);
        Mat face;
        List<Map<Mat,Point>> faceList = new ArrayList<>();
        for (Rect re : rect.toArray()) {
            Imgproc.rectangle(rgb, new Point(re.x, re.y), new Point(re.x
                    + re.width, re.y + re.height), new Scalar(0, 255, 0));
            Range r1 = new Range(re.y, re.y + re.height); //脸坐标标记
            Range r2 = new Range(re.x, re.x + re.width);//脸坐标标记
            face = new Mat(gray, r1, r2);//标准脸矩形标记
            Imgproc.resize(face, face, new Size(92, 112));//修改尺寸
            Map<Mat,Point> map = new HashMap<>();
            map.put(face, new Point(re.x, re.y));
            faceList.add(map);
        }
        return faceList;
    }

    public static void main(String[] args) {
        VideoCapture camera = new VideoCapture(0);
        if (!camera.open(0)) {
            System.err.println("相机打开有误...");
            return;
        }
        LBPHFaceRecognizer model = LBPHFaceRecognizer.create();
        model.read("/home/scorpius/Pictures/orl_faces/LBPH.xml");
        while (true) {
            Mat img = new Mat();
            if (!camera.read(img)) {
                continue;
            }
            Mat gray = new Mat();
            Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
            List<Map<Mat, Point>> faceAnalysis = faceAnalysis(img, gray);
            for(int i = 0;i<faceAnalysis.size();i++){
                Object[] toArray = faceAnalysis.get(i).keySet().toArray();
                int predict_label = model.predict_label((Mat)toArray[i]);
                if(30==predict_label){
                    Imgproc.putText(gray,
                            "CHEN", 
                            (Point) faceAnalysis.get(i).values().toArray()[i], 
                            Imgproc.FONT_HERSHEY_COMPLEX, 
                            1, 
                            new Scalar(0, 0,255));
                }
                System.out.println("当前检测标记为:" + predict_label);
            }
            HighGui.imshow("show", gray);
            HighGui.waitKey(10);
        }
    }
}
